package rmi;
import java.rmi.Naming;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
import java.util.HashMap;
import java.util.Map;

import philosoph.Philosoph;

import log.Logger;

public class RMIServerTableMaster extends UnicastRemoteObject implements RMIServerTableMasterInterface {
	private static final long serialVersionUID = -5093076042407891170L;
	private Map<String, RMIServerTableInterface> tables = new HashMap<String, RMIServerTableInterface>();
	private Object waitSync = new Object();
	private Logger logger;
	
	protected RMIServerTableMaster() throws RemoteException {
		super();
	}

	public boolean createTable(String host, int seats, Logger logger) {
		this.logger = logger;
		try {
			RMIServerTableInterface srv = (RMIServerTableInterface) Naming.lookup("//"+host+"/Table");
			boolean ret = srv.createTable(logger, seats);
			
			if(ret)
				tables.put(host, srv);
			this.logger.log("TableMaster: added table. new size: " + tables.size());
			return ret;
		} catch (Exception e) {
			return false;
		}
	}
	
	
	public void sitNEat(Philosoph phil) throws RemoteException, InterruptedException {
		String name = phil.getName();
		while(true) {
			this.logger.log("TableMaster: helps " + name + " finding a free seat.");
			for (RMIServerTableInterface table : tables.values()) {
				if(table.sitNEat(phil)) {
					this.logger.log("TableMaster: helped " + name + " successfully. Now lets wake the others.");
					wakeOthers();
					return;
				}
			}
			this.logger.log("TableMaster: found no free seat for "+name+". Put him in hold.");
			synchronized (waitSync) {
				waitSync.wait();
			}
		}
	}
	
	public void wakeOthers() {
		synchronized (waitSync) {
			waitSync.notifyAll();
		}
	}
}
